package cn.anquing.util;

import com.google.common.base.Objects;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class CalendarUtil {
	
	//定义每周的笌一天为周日
	private  static final int FIRST_DAY = Calendar.SUNDAY;
	
	//日期格式化
	private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
	
	private static void setToFirstDay(Calendar calendar) {
	        while (calendar.get(Calendar.DAY_OF_WEEK) != FIRST_DAY) {
	            calendar.add(Calendar.DATE, -1);
	        }
	} 
	
	
	//返回每周日期集合
	public static List<String> getWeekDays(){		
		Calendar calendar = Calendar.getInstance();
		List<String> weekDays = new ArrayList<>();
        setToFirstDay(calendar);        
        for (int i = 0; i < 7; i++) {
        	SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd");
            String day = dateFormat.format(calendar.getTime());
            weekDays.add(day);
            calendar.add(Calendar.DATE, 1);
        }		
		return weekDays;
	}
	
	
	
	private static SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");
	private static SimpleDateFormat format= new SimpleDateFormat("yyyy-MM-dd");
	private static String getLastDay(int year,int month){
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month);
        cal.set(Calendar.DAY_OF_MONTH, 0);
        return sdf.format(cal.getTime());
    }
	
	/**
     * 某一年某个月的每一天
     */
    public static List<String> getMonthFullDay(int year,int month,int day){
        List<String> fullDayList = new ArrayList<String>();
        if(day <= 0 ) day = 1;
        Calendar cal = Calendar.getInstance();// 获得当前日期对象
        cal.clear();// 清除信息
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);// 1月从0开始
        cal.set(Calendar.DAY_OF_MONTH, day);// 设置为1号,当前日期既为本月第一天
        int count = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        for (int j = 0; j <= (count-1);) {
            if(sdf.format(cal.getTime()).equals(getLastDay(year, month)))
                break;
            cal.add(Calendar.DAY_OF_MONTH, j == 0 ? +0 : +1);
            j++;
            fullDayList.add(sdf.format(cal.getTime()));
        }
        return fullDayList;
    }
    
    /**返回指定日期区间的日期
     * @param fromDate
     * @param toDate
     * @return
     */
    public static List<String> getBetweenDates(String fromDate, String toDate) {
    	
    	Date start = null;
    	Date end = null;
		try {
			start = format.parse(fromDate);
			end = format.parse(toDate);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}    	
		
        List<String> result = new ArrayList<String>();
        
        Calendar tempStart = Calendar.getInstance();
        tempStart.setTime(start);
        //tempStart.add(Calendar.DAY_OF_YEAR, 1);
        
        Calendar tempEnd = Calendar.getInstance();
        tempEnd.setTime(end);
        
        while (tempStart.before(tempEnd)) {
            result.add(sdf.format(tempStart.getTime()));
            tempStart.add(Calendar.DAY_OF_YEAR, 1);
        }
        //再执行一次
        result.add(sdf.format(tempStart.getTime()));
        
        return result;
    }
    
    
    
    public static Map<String,String> getTodayorWeekorMonthorQuarter(String mark)  {
    	if(Objects.equal(mark,"week")){
    		return getWeek();
    	}else if(Objects.equal(mark,"month")) {
    		return getMonth();
    	}else if(Objects.equal(mark,"quarter")) {
    		return getQuarter();
    	}else if(Objects.equal(mark,"today")){
    		Map<String, String> dayMap = new HashMap<String, String>();
    		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        	Calendar cal = Calendar.getInstance();
        	String startDay = dateFormat.format(cal.getTime());
        	String endDay = dateFormat.format(cal.getTime());
    		dayMap.put("startDay", startDay);
    		dayMap.put("endDay", endDay);
    		return dayMap;
    	}else{
    		return null;
    	}
    	
    }
    
    
    /*根据当天得到本周的第一天及最后一天日期(星期日为第一天)*/
    
    public static Map<String,String> getWeek()  {
    	
    	Map<String, String> weekMap = new HashMap<String, String>();
    	
    	SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    	Calendar cal = Calendar.getInstance();
    	
    	String dateString = dateFormat.format(new Date());
    	
		try {
			cal.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(dateString));
		} catch (ParseException e) {			
			e.printStackTrace();
		}

		int d = 0;	
		d = 1-cal.get(Calendar.DAY_OF_WEEK);
	
		cal.add(Calendar.DAY_OF_WEEK, d);
		
		//所在周开始日期
		String startDay = dateFormat.format(cal.getTime());
		cal.add(Calendar.DAY_OF_WEEK, 6);
		
		//所在周结束日期
		String endDay = dateFormat.format(cal.getTime());
		weekMap.put("startDay", startDay);
		weekMap.put("endDay", endDay);
		
		return weekMap;
    }
    
    
    /*根据当天得到本月的第一天及最后一天日期()*/
    
    public static Map<String,String> getMonth(){
    	
    	Map<String, String> monthMap = new HashMap<String, String>();
    	//获取当前月第一天：
        Calendar c = Calendar.getInstance();    
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天 
        String startDay = format.format(c.getTime());       
        
        //获取当前月最后一天
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));  
        String endDay = format.format(c.getTime());       
		
        monthMap.put("startDay", startDay);
        monthMap.put("endDay", endDay);
       
		return monthMap;
    }
    
    
     /*根据当天得到本月的第一天及最后一天日期()*/
    
     public static Map<String,String> getMonth(String dateString ){
    	
    	Map<String, String> monthMap = new HashMap<String, String>();
    	//获取当前月第一天：
        Calendar c = Calendar.getInstance();
        try {
			c.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(dateString));
		} catch (ParseException e) {
			e.printStackTrace();
		} 
        //c.add(Calendar.MONTH, 0);
        
        c.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天 
        String startDay = format.format(c.getTime());       
        
        //获取当前月最后一天
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));  
        String endDay = format.format(c.getTime());       
		
        monthMap.put("startDay", startDay);
        monthMap.put("endDay", endDay);
        System.out.println(startDay+"-"+endDay);
        
		return monthMap;
    }
    
    /*根据当天得到本季的第一天及最后一天日期()*/
    
    public static Map<String,String> getQuarter () {
    	
    	Map<String, String> quarterMap = new HashMap<String, String>();
    
        Calendar c = Calendar.getInstance();
        //当前月
        int m = c.get(Calendar.MONTH); 
        //当前年
        String y = String.valueOf(c.get(Calendar.YEAR));
    	
        String  startDay="";
        String  endDay="";
    	
    	Map<Integer,String> monMap  = new HashMap<Integer,String>();
    	monMap.put(11, "-01-01");
    	monMap.put(12, "-03-31");
    	monMap.put(21, "-04-01");
    	monMap.put(22, "-06-30");
    	monMap.put(31, "-07-01");
    	monMap.put(32, "-09-30");
    	monMap.put(41, "-10-01");
    	monMap.put(42, "-12-31");
    	
    	int q = getQuarterByMonth(m);
    	
    	switch (q) {
		case 1:
			startDay=y+monMap.get(11);
			endDay=y+monMap.get(12);
			break;
        case 2:
        	startDay=y+monMap.get(21);
			endDay=y+monMap.get(22);
			break;
        case 3:
        	startDay=y+monMap.get(31);
			endDay=y+monMap.get(32);
	        break;
        case 4:
        	startDay=y+monMap.get(41);
			endDay=y+monMap.get(42);
	        break;
		default:
			break;
		}
		
        quarterMap.put("startDay", startDay);
        quarterMap.put("endDay", endDay);
        
		return quarterMap;
    }    
    
    
    public static int getQuarterByMonth(int month) {
		int months[] = { 1, 2, 3, 4 };
		if (month >= 0 && month <= 2) // 1-3月;0,1,2
			return months[0];
		else if (month >= 3 && month <= 5) // 4-6月;3,4,5
			return months[1];
		else if (month >= 6 && month <= 8) // 7-9月;6,7,8
			return months[2];
		else
			// 10-12月;10,11,12
		return months[3];
	}
    
    /*根据某一天得到后第i个月对应的日期*/
     public static String getDay(String dateString,int i ){
    	
        Calendar c = Calendar.getInstance();
        try {
			c.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(dateString));
		} catch (ParseException e) {
			e.printStackTrace();
		} 
        c.add(Calendar.MONTH, i); 
        
        String returnMoneyDate = dateFormat.format(c.getTime());
        
		return returnMoneyDate;
     }
     
     /**
  	 * 获得几天前/几天后的日期
  	 * 
  	 * @param p
  	 *              天数 正数为p天后，负数为p天前  
  	 */
  	public static String getCaleDateString(int p) {
  		Calendar calendar = Calendar.getInstance();
  		calendar.add(Calendar.DATE, p);
  		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  		return sdf.format(calendar.getTime());
  	}
  	
  	
  	/**   
  	* @Title: getNearestWorkingDay   
  	* @Description:获取最近的工作日，法定假期无法判断
  	* @return   
  	*/ 
  	public static String getNearestWorkingDay(){
  		
  		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    	Calendar cal = Calendar.getInstance();    		
    	int day = cal.get(Calendar.DAY_OF_WEEK);
    	if(day==7){
    		cal.add(Calendar.DAY_OF_WEEK,2);
    	}else if(day==1){
    		cal.add(Calendar.DAY_OF_WEEK,1);
    	}
  		return sdf.format(cal.getTime());
  		
  	}
  	
  
  	/**   
  	* @Title: getNearestWorkingDay   
  	* @Description:获取最近的工作日，法定假期无法判断
  	* @param dateString
  	* @return 
  	* 如传入2017-05-05，就返回2017-05-08
  	*/ 
  	public static String getNearestWorkingDay(String dateString){
  		
  		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    	Calendar cal = Calendar.getInstance(); 
    	
        try {
        	cal.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(dateString));
		} catch (ParseException e) {
			e.printStackTrace();
		}    	
    	int day = cal.get(Calendar.DAY_OF_WEEK);
    	if(day==6){
    		cal.add(Calendar.DAY_OF_WEEK,3);
    	}else if(day==7){
    		cal.add(Calendar.DAY_OF_WEEK,2);
    	}else{
    		cal.add(Calendar.DAY_OF_WEEK,1);
    	}
  		return sdf.format(cal.getTime());
  		
  	}

	/**
	 * 获取相对于dateString，y年后/前的日期
	 * @param dateString
	 * @param y 正数是后，负数为前
	 * @return
	 */

	public static String getYearDateStr(String dateString,int y) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Calendar cal = Calendar.getInstance();
		try {
			cal.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(dateString));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		cal.add(Calendar.YEAR, y);
		return sdf.format(cal.getTime());

	}

	/**
	 * 获取相对于dateString，y月后/前的日期，再后推d天
	 * @param dateString
	 * @param m 正数是后，负数为前
	 * @param d 正数是后，负数为前
	 * @return
	 */

	public static String getMonthDateStr(String dateString,int m,int d) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Calendar cal = Calendar.getInstance();
		try {
			cal.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(dateString));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		cal.add(Calendar.MONTH, m);
		cal.add(Calendar.DATE,d);
		return sdf.format(cal.getTime());

	}




	public static void main(String[] args) throws ParseException {
    	
    	System.out.println(getBetweenDates("2017-01-01","2017-03-30"));
//    	    getWeek();
//    	    getMonth(); 
//    		getQuarter();
//    		getMonth("2017-02-12");    	
    	
//    	   String day = getDay("2017-03-01", 1);			
//			System.out.println(day);
    	
//    	String nearestWorkingDay = getNearestWorkingDay();
//    	System.out.println(nearestWorkingDay);
    	
//    	Map<String, String> todayorWeekorMonthorQuarter = getTodayorWeekorMonthorQuarter("quarter");
//   	System.out.println(todayorWeekorMonthorQuarter.get("startDay"));
//    	System.out.println(todayorWeekorMonthorQuarter.get("endDay"));
    	
//    	String nearestWorkingDay = getNearestWorkingDay("2017-05-07");
//        System.out.println(nearestWorkingDay);

		String yearDateStr = getMonthDateStr("2017-05-07", -1,1);
		System.out.println(yearDateStr);

	}
   
   
    
    
   
}
